package frame.laxcen.loop.demo;

import frame.laxcen.loop.BaseLoopReader;
import frame.util.ByteArrayUtil;
import frame.util.ByteUtil;
import frame.util.Ref;

public class LooperReader_Demo_0 extends BaseLoopReader {

    @Override
    protected String loop(Ref<String> pc) {

        switch(pc.get()) {

            case "loop-begin":

                readU8("FrameHeader", ByteArrayUtil::toHexString);
                readU16("ControlWord", ByteArrayUtil::toHexString);
                readU16("DataLength", (bs) -> "" + ByteUtil.byteArrayToInt(bs));

                // 循环

            case "pid-loop-begin":

                pc.swap("pid-loop-begin");

                // 如果有更复杂的逻辑 例如需要在循环体中实现 if 语意
                // 那么可以在这个阶段初始化或重置相关的局部变量

            case "pid-loop-body":

                // 这里可以修改 pc 决定跳转到哪里 例如 pid-loop-begin 或 pid-loop-body 这样可以实现
                // 该循环的目的为 尝试读取某种格式的数据 不同种类的数据使用不同的 pid 开头 pid 不一定有序 并且不能保证出现全部种类的 pid
                // 为了实现这个逻辑 需要实现 continue 语意 达到一旦读取成功就重新开始执行循环的过程

                // 设计这个类的目的就是解决这种较为复杂的帧读取操作

                if(readP16("Pid1", (byte) 0x01, (bs) -> "" + ByteUtil.byteArrayToInt(bs)))
                    return pc.swap("pid-loop-body").get();

                if(readP16("Pid2", (byte) 0x02, (bs) -> "" + ByteUtil.byteArrayToInt(bs)))
                    return pc.swap("pid-loop-body").get();

                // 注意 如果修改 pc 为 pid-loop-end 那么就可以实现 break 的语意

            case "pid-loop-end":

                // 无pid可读后会直接进入 loop-end 阶段
                // 原因可能是意料之外的 pid 的类型或 pid 全部读取完毕 (注 pid 的读取不一定按照固定的次序)

                pc.swap("pid-loop-end");
        }

        return pc.swap("loop-end").get();
    }
}
